<?php

namespace Modules\Wechat\Model\Service\Message;

use S\WeChat\Util\AccountConfigurator;

/**
 * 微信消息分发器
 *
 * 微信消息经由词分发器分发至上层应用的Service.
 *
 * @package Modules\Wechat\Model\Service\Message
 */
class Dispatcher
{

    const RESPONDER_SERVICE_NAMESPACE = '\\Service\\Wechat\\Message\\Responder';
    const NAMESPACE_DELIMITER         = '\\';

    /**
     * 分发
     *
     * 将微信发来的请求转发至上层应用的服务(Service)去处理,获取上层服务处理的结果并返回给微信服务器.
     *
     * @param \EasyWeChat\Message\AbstractMessage $message
     *
     * @return string
     */
    public static function dispatch($message)
    {
        return static::processByUpperLayerService($message);
    }

    /**
     * 通过上层应用的服务处理微信请求
     *
     * @param \EasyWeChat\Message\AbstractMessage $message EasyWeChat中message实例
     *
     * @return mixed
     */
    protected static function processByUpperLayerService($message)
    {
        return static::getUpperLayerService($message)->respond($message);
    }

    /**
     * 获取上层应用的服务
     *
     * @param object $message EasyWeChat中message实例
     *
     * @return \Modules\Wechat\Model\Service\Message\Responder\Abstraction
     */
    protected static function getUpperLayerService($message)
    {
        $path = implode(
            static::NAMESPACE_DELIMITER,
            array_filter(
                [
                    static::getUpperLayerServiceNamespace($message),
                    static::isEvent($message) ? 'Event' : '',
                    ucfirst(strtolower(static::getUpperLayerServiceName($message))),
                ]
            )
        );
        return new $path;
    }

    /**
     * 是否是事件消息
     *
     * @param object $message EasyWeChat中message实例
     *
     * @return bool
     */
    protected static function isEvent($message)
    {
        return 'event' == strtolower($message->MsgType);
    }

    /**
     * 获取上层服务名称
     *
     * @param object $message EasyWeChat中message实例
     *
     * @return mixed
     */
    protected static function getUpperLayerServiceName($message)
    {
        return static::isEvent($message) ? $message->Event : $message->MsgType;
    }

    /**
     * 获取上层服务命名空间
     *
     * @param object $message EasyWeChat中message实例
     *
     * @return array
     */
    protected static function getUpperLayerServiceNamespace($message)
    {
        return AccountConfigurator::getServiceNamespace($message->ToUserName)
            ?: static::RESPONDER_SERVICE_NAMESPACE;
    }

}

